﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

using Microsoft.TeamFoundation.WorkItemTracking.Client;


namespace Qetza.TeamFoundation.WorkItemQuery.Admin
{
    /// <summary>
    /// Command to import a work item query.
    /// </summary>
    public class CommandImportWiq : ICommand
    {
        #region ICommand Members

        /// <inheritdoc />
        public string Name
        {
            get { return "import"; }
        }

        /// <inheritdoc />
        public string HelpText
        {
            get { return ResourceStrings.ImportWiqHelpText; }
        }

        /// <inheritdoc />
        public IEnumerable<ParameterInfo> AllowedParameters
        {
            get
            {
                return new[] {
                    new ParameterInfo() { 
                        Name = CoreArgumentNames.Collection, 
                        ArgumentName = ResourceStrings.ProjectCollectionArgument, 
                        IsRequired = true, 
                        HelpText = ResourceStrings.ProjectCollectionHelpText
                        },
                    new ParameterInfo() { 
                        Name = CoreArgumentNames.Project, 
                        ArgumentName = ResourceStrings.ProjectArgument, 
                        IsRequired = true, 
                        HelpText = ResourceStrings.ProjectHelpText
                        },
                    new ParameterInfo() {
                        Name = CoreArgumentNames.QueryPath,
                        ArgumentName = ResourceStrings.QueryPathArgument,
                        IsRequired = true,
                        HelpText = ResourceStrings.Import_QueryPathHelpText
                        },
                    new ParameterInfo() {
                        Name = CoreArgumentNames.File,
                        ArgumentName = ResourceStrings.FileArgument, 
                        IsRequired = true,
                        HelpText = ResourceStrings.Import_FileHelpText
                        }
                    };
            }
        }

        /// <inheritdoc />
        public void Execute(IDictionary<string, string> parameters)
        {
            // get query hierarchy and query text
            var queryHierarchy = TfsUtility
                .GetWorkItemStore(parameters[CoreArgumentNames.Collection], parameters.ContainsKey(CoreArgumentNames.NoPrompt))
                .Projects[parameters[CoreArgumentNames.Project]]
                .QueryHierarchy;

            if (parameters[CoreArgumentNames.File][0] == '@')
            {
                // import query from file
                using (var file = new System.IO.StreamReader(parameters[CoreArgumentNames.File].Substring(1)))
                {
                    var line = default(string);
                    while ((line = file.ReadLine()) != null)
                    {
                        try
                        {
                            if (!string.IsNullOrEmpty(line))
                            {
                                this.ImportQuery(parameters, line, queryHierarchy);
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ResourceStrings.ErrorImportQuery, line, ex.Message);
                        }
                    }
                }
            }
            else
            {
                // import single query
                this.ImportQuery(parameters, parameters[CoreArgumentNames.File], queryHierarchy);
            }

            Console.WriteLine(ResourceStrings.ImportWiqCompleted);
        }

        /// <inheritdoc />
        public void ValidateParameters(IDictionary<string, string> parameters)
        {
            return;
        }

        #endregion

        #region Private Helpers

        // Replaces know variables in query text.
        private static string ReplaceVariables(string value, IDictionary<string, string> parameters)
        {
            // $$PROJECTNAME$$
            return value.Replace("$$PROJECTNAME$$", parameters[CoreArgumentNames.Project]);
        }

        // Imports a query.
        private void ImportQuery(IDictionary<string, string> parameters, string file, QueryHierarchy queryHierarchy)
        {
            var queryText = ReplaceVariables(
                    XDocument.Load(file).Descendants("Wiql").First().Value,
                    parameters
                    );

            // get/create query folder
            var folderPath = string.Empty;
            var queryName = string.Empty;

            if (parameters[CoreArgumentNames.File][0] == '@')
            {
                folderPath = parameters[CoreArgumentNames.QueryPath];
                queryName = System.IO.Path.GetFileNameWithoutExtension(file);
            }
            else
            {
                var index = parameters[CoreArgumentNames.QueryPath].LastIndexOf('/');
                folderPath = (index == -1 ? string.Empty : parameters[CoreArgumentNames.QueryPath].Substring(0, index));
                queryName = parameters[CoreArgumentNames.QueryPath].Substring(index + 1);
            }

            var folder = queryHierarchy.CreateFolder(folderPath);

            // create or update query
            var query = folder.Find(queryName);
            if (query == null)
            {
                // create query
                query = new QueryDefinition(queryName, queryText, folder);
            }
            else
            {
                if (!(query is QueryDefinition))
                {
                    // item is not a query
                    throw new Exception(string.Format(ResourceStrings.ErrorFolderAlreadyExists, parameters[CoreArgumentNames.QueryPath]));
                }

                // update query
                ((QueryDefinition)query).QueryText = queryText;
            }

            queryHierarchy.Save();
        }

        #endregion
    }
}
